package com.threez.core.exception;

import com.threez.core.exception.enums.BaseExceptionEnums;
import com.threez.core.utils.StringUtils;
import lombok.Data;

import java.util.Optional;

/**
 * 全局异常统一管理
 *
 * @title GlobalException
 * @date 2023/1/14 10:35
 * @description TODO
 */
@Data
public class GlobalException extends RuntimeException {

    private static final long serialVersionUID = 1L;
    /**
     * 所属模块
     */
    private String module;
    /**
     * 报错码
     */
    private String code;

    /**
     * 错误提示
     */
    private String message;
    /**
     * 存储错误信息
     */
    private Object errorData;

    /**
     * 自定义异常描述
     *
     * @param enumsException
     * @param des            自定义异常描述 替换String.format 中的%s
     */
    public GlobalException(BaseExceptionEnums enumsException, String... des) {
        buildGlobalException(null, enumsException, des);
    }

    /**
     * 自定义报错响应体
     *
     * @param errorData      自定义报错响应内容
     * @param enumsException
     * @param des            自定义异常描述 StringUtils.format能够替换变量模板内容中的{}
     */
    public GlobalException(Object errorData, BaseExceptionEnums enumsException, String... des) {
        buildGlobalException(errorData, enumsException, des);
    }

    /**
     * 自定义报错响应体
     * 如果errorData不为空，涉及到dubbo调用的模块，响应体一定要与dubbo的Facade的响应体中的类型一致
     * 否则使用DubboResp中getData的时候,会报类型转换错误
     *
     * @param errorData      自定义报错响应内容
     * @param enumsException
     * @param des            自定义异常描述 StringUtils.format能够替换变量模板内容中的{}
     */
    private void buildGlobalException(Object errorData, BaseExceptionEnums enumsException, String... des) {
        this.code = enumsException.getCode();
        this.module = enumsException.getModuleName();
        String msg = Optional.ofNullable(des)
                .map(item -> StringUtils.format(enumsException.getMsg(), item))
                .orElseGet(() -> enumsException.getMsg());
        this.message = msg;
        this.errorData = errorData;
    }

    @Override
    public String getMessage() {
        return message;
    }

}
